package com.juyu.miliao.api.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.juyu.miliao.api.config.SegmentedLockManager;
import com.juyu.miliao.api.dao.mysql.BeanPoolDao;
import com.juyu.miliao.api.dao.mysql.BillDetailDao;
import com.juyu.miliao.api.dao.mysql.UserWalletDao;
import com.juyu.miliao.api.domain.BeanPool;
import com.juyu.miliao.api.domain.UserWallet;
import com.juyu.miliao.common.constant.BillDetailBeansMqKey;
import com.juyu.miliao.common.domain.BeansGameDTO;
import com.juyu.miliao.common.domain.BillDetailBeans;
import com.juyu.miliao.common.exception.ConsumeRuntimeException;
import com.juyu.miliao.common.exception.IllegalParamException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDate;

/**
 * @Author: ps
 * @Date: 2019/9/16 0016 下午 1:36
 */
@Service
@Slf4j
public class BeanPoolService {
    @Resource
    private BeanPoolDao beanPoolDao;
    @Resource
    private SegmentedLockManager segmentedLockManager;
    @Resource
    private UserWalletDao userWalletDao;
    @Resource
    private BillDetailDao billDetailDao;
    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private GameDataService gameDataService;

    /**
     * @param beanPool
     * @return
     */
   // @Cacheable(value = "beanPoolCache", key = "#beanPool.userId")
    public BeanPool getBeanPool(BeanPool beanPool) {
        beanPool.setState(0);
        BeanPool yesterdayBeanPool = beanPoolDao.getBeanPool(beanPool);
        if (yesterdayBeanPool != null && yesterdayBeanPool.getState() != 2) {
            yesterdayBeanPool.setState(1);
            return yesterdayBeanPool;
        }
        beanPool.setCreateDate(LocalDate.now());
        BeanPool todayBeanPool = beanPoolDao.getBeanPool(beanPool);
        if (todayBeanPool != null) {
            return todayBeanPool;
        } else {
            BeanPool newBeanPool = new BeanPool(LocalDate.now(), 0L, 0);
            return newBeanPool;
        }
    }

    /**
     * mq更新聚宝盆
     *
     * @param beanPool
     */
  //  @CacheEvict(value = "beanPoolCache",key = "#beanPool.userId")
    public void updateBeanPoolBeans(BeanPool beanPool) {
        segmentedLockManager.sync(beanPool.getUserId() + "", () -> {
            log.info("更新聚宝盆寻豆userId:"+beanPool.getUserId());
            beanPool.setCreateDate(LocalDate.now());
            BeanPool currentBeanPool = beanPoolDao.getBeanPool(beanPool);
            if (currentBeanPool == null) {
                beanPoolDao.addBeanPool(beanPool);
            }else {
                long totalBeans = currentBeanPool.getBeans() + beanPool.getBeans();
                beanPool.setBeans(totalBeans > 100000 ? 100000 : totalBeans);
                beanPoolDao.updateBeanPoolBeans(beanPool);
            }
        });
    }

  //  @CacheEvict(value = "beanPoolCache",key = "#beanPool.userId")
    public void getBeansByUserId(BeanPool beanPool) {
        segmentedLockManager.sync(beanPool.getUserId() + "", () -> updateBeanPoolState(beanPool));
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateBeanPoolState(BeanPool beanPool) {
        beanPool.setState(0);
        BeanPool yesterdayBeanPool = beanPoolDao.getBeanPool(beanPool);
        if (yesterdayBeanPool == null) {
            throw new IllegalParamException("领取失败(已领取或无寻豆可领取)");
        }
        //更新领取状态
        beanPool.setState(2);
        int numBeanPool = beanPoolDao.updateBeanPoolState(beanPool);
        if (numBeanPool != 1) {
            throw new ConsumeRuntimeException("服务器错误");
        }
        //更新钱包
        UserWallet userWallet = new UserWallet();
        userWallet.setUserId(beanPool.getUserId());
        userWallet.setBeans(yesterdayBeanPool.getBeans());
        int numWallet = userWalletDao.plusUserWalletBeansAndDeposit(userWallet);
        if (numWallet == 1) {
            //更新beans明细
            BillDetailBeans billDetailBeans = new BillDetailBeans(beanPool.getUserId(), 31, yesterdayBeanPool.getBeans());
            billDetailDao.insertBillDetailBeans(billDetailBeans);
        }
        //领取人数
        gameDataService.increaseReliefNum(LocalDate.now(),beanPool.getUserId());
        gameDataService.increaseReliefExpend(LocalDate.now(),yesterdayBeanPool.getBeans());
    }

    /**
     * 游戏寻豆聚宝盆
     *
     * @param message
     */
    @RabbitListener(bindings = @QueueBinding(value = @Queue(BillDetailBeansMqKey.CreateGameBeansPollMQKey.QUEUE_KEY),
            exchange = @Exchange(BillDetailBeansMqKey.EXCHANGE_KEY),
            key = BillDetailBeansMqKey.CreateGameBeansPollMQKey.ROUTING_KEY))
    public void getBillDetailBeansGameMqMessage(String message) {
        if (!StringUtils.isEmpty(message)) {
            try {
                log.info("接收游戏寻豆聚宝盆mq"+ message);
                BeansGameDTO beansGameDTO = objectMapper.readValue(message, BeansGameDTO.class);
                BeanPool beanPool = new BeanPool();
                beanPool.setUserId(beansGameDTO.getUserId());
                beanPool.setBeans((Double.valueOf(-beansGameDTO.getConsume()*0.004)).longValue());
                if (beanPool.getBeans()<=0){
                    return;
                }
                updateBeanPoolBeans(beanPool);
            } catch (Exception ex) {
                log.error("处理寻豆聚宝盆错误：" + message + "|erro=" + ex);
            }
        }
    }
}
